package org.zp.study.core.provider;

import com.alibaba.fastjson.JSON;
import com.esotericsoftware.reflectasm.MethodAccess;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.zp.study.core.Constants;
import org.zp.study.core.base.Bean;
import org.zp.study.core.base.Parameter;
import org.zp.study.core.base.Result;
import org.zp.study.core.util.ExceptionUtil;

import java.util.List;
import java.util.Map;

/**
 * 提供器基类
 */
public abstract class BaseProviderRunner implements ApplicationContextAware, BaseProvider {
    protected static Logger logger = LogManager.getLogger();
    private ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public Result execute(Parameter parameter) {
        logger.info("请求：{}", JSON.toJSONString(parameter));
        Object service = applicationContext.getBean(parameter.getService());
        try {
            Long id = parameter.getId();
            Bean model = parameter.getModel();
            List<?> list = parameter.getList();
            Map<?, ?> map = parameter.getMap();
            Object object=parameter.getObject();
            Object result = null;
            MethodAccess methodAccess = MethodAccess.get(service.getClass());
            if (id != null) {
                result = methodAccess.invoke(service, parameter.getMethod(), parameter.getId());
            } else if (model != null) {
                result = methodAccess.invoke(service, parameter.getMethod(), parameter.getModel());
            } else if (list != null) {
                result = methodAccess.invoke(service, parameter.getMethod(), parameter.getList());
            } else if (map != null) {
                result = methodAccess.invoke(service, parameter.getMethod(), parameter.getMap());
            } else if(object!=null){
                result = methodAccess.invoke(service, parameter.getMethod(), parameter.getObject());
            } else {
                result = methodAccess.invoke(service, parameter.getMethod());
            }
            if (result != null) {
                Result response = new Result(result);
                logger.info("响应：{}", JSON.toJSONString(response));
                return response;
            }
            logger.info("空响应");
            return null;
        } catch (Exception e) {
            String msg = ExceptionUtil.getStackTraceAsString(e);
            logger.error(Constants.Exception_Head + msg, e);
            throw e;
        }
    }
}

